// Code scaffolded by goctl. Safe to edit.
// goctl 1.9.1

package file

import (
	"audio-server/internal/model"
	"audio-server/internal/result"
	"audio-server/internal/svc"
	"audio-server/internal/types"
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"math/rand"
	"mime/multipart"
	"path/filepath"
	"strings"
	"time"

	"github.com/volcengine/ve-tos-golang-sdk/v2/tos"
	"github.com/zeromicro/go-zero/core/logx"
)

type FileUploadLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewFileUploadLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FileUploadLogic {
	return &FileUploadLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *FileUploadLogic) FileUpload(file multipart.File, header *multipart.FileHeader) (resp *types.BaseMsgResp, err error) {
	userId, _ := l.ctx.Value("userId").(json.Number).Int64()
	uploadDir := "uploads/"
	filename := header.Filename
	fileSize := header.Size
	ext := filepath.Ext(filename)
	baseName := strings.TrimSuffix(filename, ext)
	safeFilename := baseName + "_" + generateRandomString(8) + ext
	filePath := uploadDir + safeFilename
	fmt.Printf("文件名: %s\n", filePath)
	client := l.svcCtx.TOSClient
	_, err = client.PutObjectV2(l.ctx, &tos.PutObjectV2Input{
		PutObjectBasicInput: tos.PutObjectBasicInput{
			Bucket: l.svcCtx.Config.TosConfig.Bucket,
			Key:    filePath,
		},
		Content: file,
	})
	if err != nil {
		return result.Fail(err.Error()), err
	}
	url := "https://audio-server.tos-cn-guangzhou.volces.com/"

	res := fmt.Sprintf("%s%s", url, filePath)

	// 保存到数据库
	fileModel := model.NewSysFileModel(l.svcCtx.Conn)

	_, err = fileModel.Insert(l.ctx, &model.SysFile{
		Name:       filename,
		Src:        sql.NullString{String: res, Valid: true},
		ParentId:   0,
		UpdateTime: time.Now(),
		IsDir:      sql.NullInt64{Int64: int64(0), Valid: true},
		ExtendName: sql.NullString{String: strings.TrimPrefix(ext, "."), Valid: true},
		Size:       fileSize,
		UserId:     sql.NullInt64{Int64: userId, Valid: true},
	})
	return result.Success(res), nil
}

func generateRandomString(length int) string {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, length)
	for i := range b {
		b[i] = charset[rand.Intn(len(charset))]
	}
	return string(b)
}
